/* ---------------------------------------- *\
 * FREDDY FROG - AND THE DOWNSTREAM VOYAGE  *
 *   Hochschule Emden Leer - WS 2011/12     *
 *                  ***                     *
 *     Viktor Grass   (El Presidente)       * 
 *     Michael Sürken (Programmierung)      *
 *     Rainer Geiger  (Programmierung)      *
\* ---------------------------------------- */
package freddyfrog;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.Sound;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.AngelCodeFont;
import org.newdawn.slick.Font;
import java.util.Random;
import java.io.*;

public class FreddyFrog extends BasicGame {         // Klasse FreddyFrog abgeleitet von der Slick Basic 
    // Game Klasse (welche zu Game gehoert)

    Image water;
    private int waterX1 = 0;
    private int waterX2 = 0;
    private int waterY1 = 0;
    private int waterY2 = -600;
    private Lilypad lilypad1;
    private Lilypad lilypad2;
    private Lilypad lilypad3;
    private Lilypad lilypad4;
    private Sound jump;
    private Frog frog;
    private int frogX = 300;
    private int frogY = 350;
    private Input input;
    private int speed;
    private int score = -1;
    private int highscore = 0;
    private boolean pause = false;
    private boolean gameOver = false;
    Random rand = new Random(30);
    private Font scoreFont;

    public FreddyFrog() {                                           // Spielename
        super("Freddy Frog - And The Downstream Voyage");
    }

    @Override
    public void init(GameContainer gc) throws SlickException {      // Spielresourcen beim Start laden, Daten initialisieren 

        water = new Image("data/water.png");                        // Hintergrundbild wird geladen (nicht per render()) gezeichnet
        lilypad1 = new Lilypad(new Image("data/lilypad.png"));      // Seerosen werden erstellt
        lilypad2 = new Lilypad(new Image("data/lilypad.png"));
        lilypad3 = new Lilypad(new Image("data/lilypad.png"));
        lilypad4 = new Lilypad(new Image("data/lilypad.png"));
        
        jump = new Sound("data/jump.wav");
        frog = new Frog(new Image("data/frog.png"), gc.getInput()); // Froschobjekt (-->Gameobjekt) wird inkl. Uebergebenen Bildgeladen
        frog.setX(frogX);                                           // Startkoordinaten des Frosches
        frog.setY(frogY);
        lilypad1.setX(100);                                         // Seerosen werden gesetzt
        lilypad1.setY(500);
        lilypad2.setX(300);                                         // Startseerose, auf dem der Frosch sitzt
        lilypad2.setY(350);
        lilypad3.setX(500);
        lilypad3.setY(200);
        lilypad4.setX(700);
        lilypad4.setY(600);
        try {
            highscore = readHS("data/highscore.sav");               // gibt es schon einen Highscore ?       
        } catch (Exception e) {
        }

        scoreFont = new AngelCodeFont("data/hiero.fnt", // Schrifart aus Bild und Skript
                new Image("data/hiero.png"));
        gc.setMultiSample(2);                                       // Fullscreen Multisampling incl. Hardware Antialiasing
        gc.setMouseCursor("data/cursor.png", 10, 10);
    }

    @Override
    public void update(GameContainer gc, int delta) throws SlickException { // Spielschleife (Gameloop) mit uebergebenem Container 

        input = gc.getInput();                                              // Auslesen von Tastenanschlaegen
        if (input.isKeyPressed(Input.KEY_ESCAPE)) {                         // bei Escape Spiel beenden
            if (highscore < score) {                                            // Highscore neu schreiben wenn beserer Wert 
                try {
                    writeHS("data/highscore.sav", score);
                } catch (Exception e) {
                }

            }
            gc.exit();                                                      // Spiel beenden
        }
        if (input.isKeyPressed(Input.KEY_P)) {                              // Spiel pausieren
            pause = !pause;
        }
        if (pause) {                                                        // 
        } else if (gameOver) {
        } else {
            if (score >= speed * 20) {                                      // Geschwindigkeit des Spiels erhöhen 
                speed++;
            }

            if (waterY1 > 599) {                                            // Wasser zurücksetzen
                waterY1 = 0;
                waterY2 = -600;
            }
            waterY1 = waterY1 + speed;                                      // Geschwindigkeit der Oberfläche erhöhen 
            waterY2 = waterY2 + speed;

            if (lilypad1.getY() >= 630) {                                   // Seerose außerhalb des Spielfeldes ?
                lilypad1.setY(-rand.nextInt(100));                          // Seerose neu setzen
                lilypad1.setUsed(false);                                    // Seerose nicht mehr markiert
            }
            if (lilypad2.getY() >= 630) {
                lilypad2.setY(-rand.nextInt(200));
                lilypad2.setUsed(false);
            }
            if (lilypad3.getY() >= 630) {
                lilypad3.setY(-rand.nextInt(300));
                lilypad3.setUsed(false);
            }
            if (lilypad4.getY() >= 630) {
                lilypad4.setY(-rand.nextInt(150));
                lilypad4.setUsed(false);
            } else {
                lilypad1.setY(lilypad1.getY() + speed);                 // wenn Seerose noch im Spielfeld, diese nach der
                lilypad2.setY(lilypad2.getY() + speed);                 // aktuellen Geschwindigkeit weitersetzen
                lilypad3.setY(lilypad3.getY() + speed);
                lilypad4.setY(lilypad4.getY() + speed);
            }

            frogY = frogY + speed;                                      // Frosch ebenfalls weitersetzen
            frog.setY(frogY);
            frog.setX(frogX);

            if (input.isMousePressed(Input.MOUSE_LEFT_BUTTON)) {
                // der Frosch springen
                jump.play();
                frogX = input.getMouseX();                              // neue Koordinaten für den Frosch durch Mausklick
                frogY = input.getMouseY();

            }
            if (lilypad1.checkCollsion(frog) == true) {                 // Seerose mit Frosch kollidiert?
                if (!lilypad1.getUsed()) {                              // Score nur erhöhen wenn Seerose nocht nicht markiert
                    score++;
                    lilypad1.setUsed(true);                             // Seerose markieren
                }
            } else if (lilypad2.checkCollsion(frog) == true) {
                if (!lilypad2.getUsed()) {
                    score++;
                    lilypad2.setUsed(true);
                }
            } else if (lilypad3.checkCollsion(frog) == true) {
                if (!lilypad3.getUsed()) {
                    score++;
                    lilypad3.setUsed(true);
                }
            } else if (lilypad4.checkCollsion(frog) == true) {
                if (!lilypad4.getUsed()) {
                    score++;
                    lilypad4.setUsed(true);
                }
            } else {
                if (score > 0) {                                            // wenn Seerose nicht getroffen
                    gameOver = true;
                }
                if (highscore < score) {                                      // Highscore neu schreiben wenn verbessert
                    try {
                        writeHS("data/highscore.sav", score);
                    } catch (Exception e) {
                    }

                }
            }

            if (frog.getY() >= 600) {                               // wenn der Frosch außerhalb des Spielbereichs kommt
                gameOver = true;
                if (highscore < score) {                                // neuer Highscore
                    try {
                        writeHS("data/highscore.sav", score);
                    } catch (Exception e) {
                    }
                }
            }
            frog.update(delta);
            lilypad1.update(delta);
            lilypad2.update(delta);
            lilypad3.update(delta);
            lilypad4.update(delta);
        }

    }

    public void render(GameContainer gc, Graphics g) throws SlickException { // Grafiken darstellen (unabhaengig von update 
        // so oft wie moeglich )
        water.draw(waterX1, waterY1);                                       // Wasseroberfläche darstellen
        water.draw(waterX2, waterY2);
        lilypad1.draw(g);                                                    // Seerosen darstellen
        lilypad2.draw(g);
        lilypad3.draw(g);
        lilypad4.draw(g);
        g.setFont(scoreFont);                                               // Schriftart setzen
        if (pause) {
            g.drawString("Paused", 300, 300);
        }

        if (gameOver) {
            g.drawString("Game Over!", 300, 300);
        }

        g.drawString("Score: " + score, (float) 550, (float) 5);
        g.drawString("Highscore: " + highscore, (float) 10, (float) 5);
        frog.draw(g);                                                       // Froschobjekt ausgeben

    }

    public static void main(String[] args) throws SlickException {

        AppGameContainer app = new AppGameContainer(new FreddyFrog());	// neue Desktop Application mit einem neuen 
        // Objekt von FreddyFrog
        app.setTargetFrameRate(60);
        app.setVSync(true);                                             // Vertikale Synchronisation EIN
        app.setShowFPS(false);
        app.setDisplayMode(800, 600, true);				// Displayanzeige in Pixeln(x,y), kein Fullscreen
        app.start();	// starten des Spielablaufs

    }

    public void writeHS(String file, int hscore) throws Exception {     // Highscore schreiben
        FileOutputStream fStream = new FileOutputStream(file, false);
        fStream.write(hscore);
        fStream.close();
    }

    public int readHS(String file) throws Exception {                   // Highscore lesen
        int rscore = 0;
        FileInputStream fStream = new FileInputStream(file);
        rscore = fStream.read();
        fStream.close();
        return rscore;
    }
}
